# !/usr/bin/env python
# -*- coding: utf-8 -*-

# 将一个给定字符串 s 根据给定的行数 numRows ，以从上往下、从左到右进行 Z 字形排列。
#
# 比如输入字符串为 "PAYPALISHIRING" 行数为 3 时，排列如下：
#
# P   A   H   N
# A P L S I I G
# Y   I   R
# 之后，你的输出需要从左往右逐行读取，产生出一个新的字符串，比如："PAHNAPLSIIGYIR"。
#
# 请你实现这个将字符串进行指定行数变换的函数：
#
# string convert(string s, int numRows);
#  
#
# 示例 1：
#
# 输入：s = "PAYPALISHIRING", numRows = 3
# 输出："PAHNAPLSIIGYIR"
# 示例 2：
# 输入：s = "PAYPALISHIRING", numRows = 4
# 输出："PINALSIGYAHRPI"
# 解释：
# P     I    N
# A   L S  I G
# Y A   H R
# P     I
# 示例 3：
#
# 输入：s = "A", numRows = 1
# 输出："A"
#  
#
# 提示：
#
# 1 <= s.length <= 1000
# s 由英文字母（小写和大写）、',' 和 '.' 组成
# 1 <= numRows <= 1000
#
# 来源：力扣（LeetCode）
# 链接：https://leetcode.cn/problems/zigzag-conversion
# 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        length = len(s)
        if length <= 1 or numRows <= 1:
            return s
        z_count = 2 * numRows - 2
        count = length // z_count
        mod = length % z_count
        numCols = count * (numRows - 1)
        if mod > 0 and mod <= numRows:
            numCols += 1
        elif mod > numRows and mod < z_count:
            numCols += (mod - numRows + 1)
        arr = [[None] * numCols for _ in range(numRows)]
        for i in range(length):
            m = i // z_count
            n = i % z_count
            k = numRows - 1
            if 0 <= n < numRows:
                row = n
                col = k * m
            elif numRows <= n < z_count:
                row = 2 * numRows - n - 2
                col = k * m + (n - numRows + 1)
            else:
                row = 1
                col = k * m + 2
            arr[row][col] = s[i]
        r = ""
        for i in range(numRows):
            for j in range(numCols):
                e = arr[i][j]
                if e is not None:
                    r += e
            # print(arr[i])
        return r

    def convert2(self, s: str, numRows: int) -> str:
        length = len(s)
        if length <= 1 or numRows <= 1:
            return s
        z_count = 2 * numRows - 2
        count = length // z_count
        mod = length % z_count
        numCols = count * (numRows - 1)
        if mod > 0 and mod <= numRows:
            numCols += 1
        elif mod > numRows and mod < z_count:
            numCols += (mod - numRows + 1)
        r = ""
        for i in range(numRows):
            if i == 0 or i == (numRows - 1):
                j = 0
                index = 0
                while j < numCols:
                    k = index * z_count + i
                    if k < length:
                        r += s[k]
                    index += 1
                    j += (numRows - 1)
            else:
                j = 0
                index = 0
                while j < numCols:
                    k = index * z_count + i
                    if k < length:
                        r += s[k]
                    k2 = index * z_count + z_count - i
                    if k2 < length:
                        r += s[k2]
                    index += 1
                    j += (numRows - 1)
        return r

    def convert3(self, s: str, numRows: int) -> str:
        length = len(s)
        if length <= 1 or numRows <= 1:
            return s
        z_count = 2 * numRows - 2
        count = length // z_count
        total = count
        mod = length % z_count
        if mod > 0:
            total += 1
        numCols = count * (numRows - 1)
        if mod > 0 and mod <= numRows:
            numCols += 1
        elif mod > numRows and mod < z_count:
            numCols += (mod - numRows + 1)
        r = s
        for i in range(1, length):
           m = i // z_count
           n = i % z_count
           pos = m * z_count
           r[pos] = s[i]
        return r


if __name__ == '__main__':
    s = Solution()
    print(s.convert("PAYPALISHIRING", 2))
    print(s.convert("PAYPA", 4))
    print(s.convert("PAYPALISHIRING", 4))
    print(s.convert("A", 1))
    print(s.convert("PAYPALISHIRING", 3), end="\n")
    print("", end="\n")
    print(s.convert2("PAYPALISHIRING", 2))
    print(s.convert2("PAYPA", 4))
    print(s.convert2("PAYPALISHIRING", 4))
    print(s.convert2("A", 1))
    print(s.convert2("PAYPALISHIRING", 3))
